package modbus_slave

import (
	"backend/internal/core/types"
	"backend/internal/db/model"
	"github.com/zeromicro/go-zero/core/logx"
	"sync"
)

// SlaveManager 管理 Modbus 从站的结构体
type SlaveManager struct {
	slaveMap map[string]*ModbusSlave
	mu       sync.RWMutex
}

// NewSlaveManager 创建一个新的 SlaveManager 实例
func NewSlaveManager() *SlaveManager {
	return &SlaveManager{
		slaveMap: make(map[string]*ModbusSlave),
	}
}

// SetAllSlave 从数据库获取从站列表并创建对应的 Modbus 从站
func (sm *SlaveManager) SetAllSlave(slaveList []model.Slave) {
	for _, slave := range slaveList {
		slaveName := slave.Name
		ip := slave.IP
		port := slave.Port
		protocol := slave.Protocol

		switch protocol {
		case types.Tcp:
			sm.AddModbusTCPSlave(slaveName, ip, port)
		case types.RtuOverTcp:
			sm.AddModbusRtuOverTcpSlave(slaveName, ip, port)
		case types.Rtu:
			sm.AddModbusRtuSlave(slaveName, "COM1", 9600, "N", 1, 8, 1000)
			// 可添加其他协议类型
		default:
			logx.Errorf("不支持的协议类型: %v", protocol)
		}
	}
}

// ClearAllSlaves 清理 slaveMap 里的所有 Modbus 从站
func (sm *SlaveManager) ClearAllSlaves() {
	sm.mu.Lock()
	defer sm.mu.Unlock()

	for slaveName, slave := range sm.slaveMap {
		slave.Disconnect()
		delete(sm.slaveMap, slaveName)
		logx.Infof("删除从站: %s", slaveName)
	}
}

// AddModbusTCPSlave 添加一个 Modbus Tcp 从站
func (sm *SlaveManager) AddModbusTCPSlave(slaveName, ip string, port int32) {
	sm.mu.Lock()
	defer sm.mu.Unlock()

	if _, exists := sm.slaveMap[slaveName]; !exists {
		tcpConfig := &types.TcpConfig{
			Host:         ip,
			Port:         port,
			ProtocolType: types.Tcp,
		}
		slave := NewModbusSlave(types.Tcp, tcpConfig, nil)
		sm.slaveMap[slaveName] = slave
	}
}

// AddModbusRtuOverTcpSlave 添加一个 Modbus Rtu over Tcp 从站
func (sm *SlaveManager) AddModbusRtuOverTcpSlave(slaveName, ip string, port int32) {
	sm.mu.Lock()
	defer sm.mu.Unlock()

	if _, exists := sm.slaveMap[slaveName]; !exists {
		tcpConfig := &types.TcpConfig{
			Host:         ip,
			Port:         port,
			ProtocolType: types.RtuOverTcp,
		}
		slave := NewModbusSlave(types.RtuOverTcp, tcpConfig, nil)
		sm.slaveMap[slaveName] = slave
	}
}

// AddModbusRtuSlave 添加一个 Modbus Rtu 从站
func (sm *SlaveManager) AddModbusRtuSlave(slaveName, port string, baudrate int32, parity string, stopbits, bytesize int32, timeout int32) {
	sm.mu.Lock()
	defer sm.mu.Unlock()

	if _, exists := sm.slaveMap[slaveName]; !exists {
		rtuConfig := &types.RtuConfig{
			Port:     port,
			Baudrate: baudrate,
			Parity:   parity,
			Stopbits: stopbits,
			Bytesize: bytesize,
			Timeout:  timeout,
		}
		slave := NewModbusSlave(types.Rtu, nil, rtuConfig)
		sm.slaveMap[slaveName] = slave
	}
}

// EditSlave 编辑现有的 Modbus 从站
func (sm *SlaveManager) EditSlave(oldSlaveName string, protocolType types.ProtocolType, slaveName, ip string, port int32) error {
	if err := sm.DeleteSlave(oldSlaveName); err != nil {
		logx.Errorf("编辑从站失败: 删除旧从站 %s 时出错: %v", oldSlaveName, err)
		return err
	}

	switch protocolType {
	case types.Tcp:
		sm.AddModbusTCPSlave(slaveName, ip, port)
	case types.RtuOverTcp:
		sm.AddModbusRtuOverTcpSlave(slaveName, ip, port)
	// 可添加其他协议类型
	case types.Rtu:
		sm.AddModbusRtuSlave(slaveName, "COM1", 9600, "N", 1, 8, 1000)
	default:
		logx.Errorf("不支持的协议类型: %v", protocolType)
	}
	return nil
}

// DeleteSlave 删除指定的 Modbus 从站
func (sm *SlaveManager) DeleteSlave(slaveName string) error {
	if slave, exists := sm.slaveMap[slaveName]; exists {
		slave.Disconnect()
		delete(sm.slaveMap, slaveName)
		logx.Infof("删除从站: %s", slaveName)
		return nil
	}
	return nil
}

// GetSlave 获取指定名称的 Modbus 从站
func (sm *SlaveManager) GetSlave(slaveName string) *ModbusSlave {
	sm.mu.RLock()
	defer sm.mu.RUnlock()

	if slave, exists := sm.slaveMap[slaveName]; exists {
		return slave
	}
	return nil
}
